package com.afkt.project.ui;

import com.afkt.project.util.LogUtils;
import com.ohos.afkt.ResourceTable;
import ohos.agp.components.Attr;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Image;
import ohos.agp.render.*;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;

import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;

public class ShapeImage extends Image {

    private static final String TAG = "ShapeImage";

    private PixelMapHolder pixelMapHolder;//像素图片持有者
    private RectFloat rectDst;//目标区域
    private RectFloat rectSrc;//源区域

    public ShapeImage(Context context) throws NotExistException, WrongTypeException, IOException {
        super(context, null);
    }

    public ShapeImage(Context context, AttrSet attrSet) throws NotExistException, WrongTypeException, IOException {
        super(context, attrSet);
        //init(context, attrSet);
    }

    private void init(Context context, AttrSet attrSet) throws NotExistException, WrongTypeException, IOException {

        LogUtils.error(TAG, "getInteger" + getInteger(attrSet.getAttr(context.getResourceManager().getElement(ResourceTable.String_image).getString()), 0) + "");
        switch (getInteger(attrSet.getAttr(context.getResourceManager().getElement(ResourceTable.String_image).getString()), 0)) {
            case 1:
                setPixelMapAndCircle(ResourceTable.Media_bg_wallpaper);
                break;
            case 2:
                setPixelMapAndRoundRectAndStroke(ResourceTable.Media_bg_wallpaper, 60);
                break;
            case 3:
                setPixelMapClip(ResourceTable.Media_bg_wallpaper, 70);
                break;
            case 4:
                setPixelMapCube(ResourceTable.Media_bg_wallpaper);
                break;
            case 5:
                setPixelMapSector(ResourceTable.Media_bg_wallpaper);
                break;
            case 6:
                setPixelMapTwoClip(ResourceTable.Media_bg_wallpaper);
            case 7:
                setPixelMapBesselCurve(ResourceTable.Media_bg_wallpaper);
                break;
            case 8:
                setPixelMapOvalAndClip(ResourceTable.Media_bg_wallpaper);
                break;
            case 9:
                setPixelMapTwoClipAndRadius(ResourceTable.Media_bg_wallpaper, 60);
                break;
        }
    }


    private int getInteger(Optional<Attr> attr, int defaultValue) {
        if (attr.isPresent()) {
            return attr.get().getIntegerValue();
        } else {
            return defaultValue;
        }
    }

    /**
     * 加载包含该控件的xml布局，会执行该构造函数
     *
     * @param context
     * @param attrSet
     * @param styleName
     */
    public ShapeImage(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        LogUtils.error(TAG, "ShapeImage");
    }

    /**
     * 对外调用的api，设置圆形图片方法
     *
     * @param resId
     */
    public void setPixelMapAndCircle(int resId) {
        PixelMap pixelMap = getPixelMap(resId);
        putPixelMap(pixelMap);
        onCircleDraw();
    }

    /**
     * 对外调用的api，设置圆角图片方法
     *
     * @param resId
     * @param radius
     */
    public void setPixelMapAndRoundRect(int resId, int radius) {
        PixelMap pixelMap = getPixelMap(resId);
        putPixelMap(pixelMap);
        onRoundRectDraw(radius);
    }

    /**
     * 对外调用的api，设置圆角带边框的图片方法
     *
     * @param resId
     * @param radius
     */
    public void setPixelMapAndRoundRectAndStroke(int resId, int radius) {
        PixelMap pixelMap = getPixelMap(resId);
        putPixelMap(pixelMap);
        onRoundRectAndStrokeDraw(radius);
    }

    /**
     * 对外调用的api，指定图片的切边，对图片 处理
     *
     * @param resId
     * @param roundPx
     */
        public void setPixelMapClip(int resId, int roundPx) {
        PixelMap pixelMap = getPixelMap(resId);
        putPixelMap(pixelMap);
        onRoundRectClip(roundPx);
    }

    /**
     * 对外调用的api，指定图片为立方体带边框
     *
     * @param resId
     */
    public void setPixelMapCube(int resId) {
        PixelMap pixelMap = getPixelMap(resId);
        putPixelMap(pixelMap);
        onRoundRectCube();
    }

    /**
     * 对外调用的api，指定图片为扇形
     *
     * @param resId
     */
    public void setPixelMapSector(int resId) {
        PixelMap pixelMap = getPixelMap(resId);
        putPixelMap(pixelMap);
        onRoundRectSector();
    }

    /**
     * 对外调用的api，指定图片椭圆和切角
     *
     * @param resId
     */
    public void setPixelMapOvalAndClip(int resId) {
        PixelMap pixelMap = getPixelMap(resId);
        putPixelMap(pixelMap);
        onRoundRectOvalAndClip();
    }

    /**
     * 对外调用的api，指定图片两个切角 加圆角30
     *
     * @param resId
     * @param radius
     */
    public void setPixelMapTwoClipAndRadius(int resId, int radius) {
        PixelMap pixelMap = getPixelMap(resId);
        putPixelMap(pixelMap);
        onPixelMapTwoClipAndRadius(radius);
    }

    /**
     * 对外调用的api，指定图片两个切角
     *
     * @param resId
     */
    public void setPixelMapTwoClip(int resId) {
        PixelMap pixelMap = getPixelMap(resId);
        putPixelMap(pixelMap);
        onPixelMapTwoClip();
    }


    /**
     * 对外调用的api，切屏贝塞尔曲线
     *
     * @param resId
     */
    public void setPixelMapBesselCurve(int resId) {
        PixelMap pixelMap = getPixelMap(resId);
        putPixelMap(pixelMap);
        onPixelMapBesselCurve();
    }

    //使用Canvas 画贝塞尔曲线
    private void onPixelMapBesselCurve() {
        //添加绘制任务
        this.addDrawTask((view, canvas) -> {
            if (pixelMapHolder == null) {
                return;
            }
            synchronized (pixelMapHolder) {
                //给目标区域赋值，宽度和高度取自xml配置文件中的属性
                rectDst = new RectFloat(0, 0, getWidth(), getHeight());
                canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, 0, 0);

                canvas.clipRect(rectDst, Canvas.ClipOp.INTERSECT);
                Paint paint = new Paint();
                paint.setAntiAlias(true);                           //设置画笔为无锯齿
                paint.setColor(Color.WHITE);                        //设置画笔颜色

                Path path = new Path();
                path.moveTo(0, 0);
                path.cubicTo(new Point(0, getHeight()), new Point(10, getWidth()), new Point(getWidth(), getHeight()));
                path.lineTo(0, getHeight());
                path.lineTo(0, 0);
                path.close();
                canvas.drawPath(path, paint);

                Path path1 = new Path();
                path1.moveTo(0, 0);
                path1.cubicTo(new Point(getWidth() + 20, 0), new Point(getWidth() - 10, 0), new Point(getWidth(), getHeight()));
                path1.lineTo(getWidth(), 0);
                path1.lineTo(0, 0);
                path1.close();
                canvas.drawPath(path1, paint);

                pixelMapHolder = null;
            }
        });
    }

    //使用canvas 画出两个切角
    private void onPixelMapTwoClip() {
        //添加绘制任务
        this.addDrawTask((view, canvas) -> {
            if (pixelMapHolder == null) {
                return;
            }
            synchronized (pixelMapHolder) {
                //给目标区域赋值，宽度和高度取自xml配置文件中的属性
                rectDst = new RectFloat(0, 0, getWidth(), getHeight());
                canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, 0, 0);

                canvas.clipRect(rectDst, Canvas.ClipOp.INTERSECT);
                Paint paint = new Paint();
                paint.setAntiAlias(true);                           //设置画笔为无锯齿
                paint.setColor(Color.WHITE);                        //设置画笔颜色


                RectFloat rectFloat = new RectFloat(0, 0, getWidth() * 2, (getHeight() - 50) * 2);

                RectFloat rectFloat1 = new RectFloat(-getWidth(), 0, getWidth(), (getHeight() - 50) * 2);

                Path path = new Path();
                path.moveTo(0, getHeight());
                path.arcTo(rectFloat, 180, 90);
                path.lineTo(0, 0);
                canvas.drawPath(path, paint);

                Path path1 = new Path();
                path1.moveTo(getWidth(), getHeight());
                path1.arcTo(rectFloat1, 0, -90);
                path1.lineTo(getWidth(), 0);
                path1.close();
                canvas.drawPath(path1, paint);

                pixelMapHolder = null;
            }
        });
    }

    //使用canvas 画出两个切角加圆角30
    private void onPixelMapTwoClipAndRadius(int radius) {
        //添加绘制任务
        this.addDrawTask((view, canvas) -> {
            if (pixelMapHolder == null) {
                return;
            }
            synchronized (pixelMapHolder) {
                //给目标区域赋值，宽度和高度取自xml配置文件中的属性
                rectDst = new RectFloat(0, 0, getWidth(), getHeight());
                canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, radius, radius);

                canvas.clipRect(rectDst, Canvas.ClipOp.INTERSECT);
                Paint paint = new Paint();
                paint.setAntiAlias(true);                           //设置画笔为无锯齿
                paint.setColor(Color.WHITE);                        //设置画笔颜色


                RectFloat rectFloat = new RectFloat(0, 0, getWidth() * 2, (getHeight() - 200) * 2);

                RectFloat rectFloat1 = new RectFloat(-getWidth(), 0, getWidth(), (getHeight() - 200) * 2);

                Path path = new Path();
                path.moveTo(0, getHeight());
                path.arcTo(rectFloat, 180, 90);
                path.lineTo(0, 0);
                canvas.drawPath(path, paint);

                Path path1 = new Path();
                path1.moveTo(getWidth(), getHeight());
                path1.arcTo(rectFloat1, 0, -90);
                path1.lineTo(getWidth(), 0);
                path1.close();
                canvas.drawPath(path1, paint);

                pixelMapHolder = null;
            }
        });
    }

    //使用canvas 画椭圆和切角
    private void onRoundRectOvalAndClip() {
        //添加绘制任务
        this.addDrawTask((view, canvas) -> {
            if (pixelMapHolder == null) {
                return;
            }
            synchronized (pixelMapHolder) {
                //给目标区域赋值，宽度和高度取自xml配置文件中的属性
                rectDst = new RectFloat(0, 0, getWidth(), getHeight() / 2);

                canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, 200, 200);

                canvas.clipRect(rectDst, Canvas.ClipOp.INTERSECT);

                Paint paint = new Paint();
                paint.setAntiAlias(true);                           //设置画笔为无锯齿
                paint.setColor(Color.WHITE);                        //设置画笔颜色

                Path path1 = new Path();
                path1.moveTo(getWidth() / 4 * 3, 0);
                path1.lineTo(getWidth(), 0);
                path1.lineTo(getWidth(), getHeight() / 4);
                path1.close();
                canvas.drawPath(path1, paint);

                Path path2 = new Path();
                path2.moveTo(getWidth(), getHeight() / 4);
                path2.lineTo(getWidth(), getHeight() / 2);
                path2.lineTo(getWidth() / 4 * 3, getHeight() / 2);
                path2.close();
                canvas.drawPath(path2, paint);

                pixelMapHolder = null;
            }
        });

    }

    //使用Canvase 画图片扇形
    public void onRoundRectSector() {
        //添加绘制任务
        this.addDrawTask((view, canvas) -> {
            if (pixelMapHolder == null) {
                return;
            }
            synchronized (pixelMapHolder) {
                //给目标区域赋值，宽度和高度取自xml配置文件中的属性
                rectDst = new RectFloat(0, 0, getWidth(), getHeight());
                canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, 0, 0);

                canvas.clipRect(rectDst, Canvas.ClipOp.INTERSECT);
                Paint paint = new Paint();
                paint.setAntiAlias(true);                           //设置画笔为无锯齿
                paint.setColor(Color.WHITE);                        //设置画笔颜色


                Path path = new Path();
                path.moveTo(0, 0);
                path.arcTo(new RectFloat(-getWidth(), 0, getWidth(), getWidth() * 2), -90, 90);
                path.lineTo(getWidth(), 0);
                path.close();
                canvas.drawPath(path, paint);

           /*     canvas.clipRect(rectDst, Canvas.ClipOp.INTERSECT);
                Paint paint = new Paint();
                paint.setAntiAlias(true);                           //设置画笔为无锯齿
                paint.setColor(Color.WHITE);                        //设置画笔颜色

                Arc arc = new Arc();
                arc.setArc(-90,90,true);
                canvas.drawArc(rectDst,arc,paint);
*/
                //创建画笔
            /*    Paint paint = new Paint();
                paint.setBlendMode(BlendMode.SRC_IN);
                paint.setStyle(Paint.Style.FILL_STYLE);
                paint.setStrokeWidth(2);
                paint.setColor(Color.WHITE);
                canvas.drawPixelMapHolderRect(pixelMapHolder,rectDst, paint);
                canvas.drawCircle(0,getHeight(),getHeight(),paint);*/

                pixelMapHolder = null;
            }
        });
    }

    //使用canvas 画立方体并带边框
    private void onRoundRectCube() {
        //添加绘制任务
        this.addDrawTask((view, canvas) -> {
            if (pixelMapHolder == null) {
                return;
            }
            synchronized (pixelMapHolder) {
                //给目标区域赋值，宽度和高度取自xml配置文件中的属性
                rectDst = new RectFloat(0, 0, getWidth(), getHeight());
                canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, 0, 0);
                //绘制圆角图片
                canvas.clipRect(rectDst, Canvas.ClipOp.INTERSECT);
                Paint paint = new Paint();
                paint.setAntiAlias(true);                           //设置画笔为无锯齿
                paint.setColor(Color.WHITE);                        //设置画笔颜色

                canvas.drawPath(pathLeftTop(getWidth() / 2), paint);
                canvas.drawPath(pathRightTop(getWidth() / 2), paint);
                canvas.drawPath(pathLeftBottom(getWidth() / 2), paint);
                canvas.drawPath(pathRightBottom(getWidth() / 2), paint);


                Paint roundPaint = new Paint();
                roundPaint.setAntiAlias(true);
                roundPaint.setStyle(Paint.Style.STROKE_STYLE);
                roundPaint.setStrokeWidth(15);
                roundPaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
                roundPaint.setColor(Color.BLACK);


                Point startPoint = new Point(5, getHeight() / 2 + 5);
                Point endPoint = new Point(getWidth() / 2 + 5, 5);
                canvas.drawLine(startPoint, endPoint, roundPaint);

                Point startPoint1 = new Point(getWidth() / 2 + 5, 5);
                Point endPoint1 = new Point(getWidth() - 5, getHeight() / 2 - 5);
                canvas.drawLine(startPoint1, endPoint1, roundPaint);

                Point startPoint2 = new Point(getWidth() - 5, getHeight() / 2 - 5);
                Point endPoint2 = new Point(getWidth() / 2 - 5, getHeight() - 5);
                canvas.drawLine(startPoint2, endPoint2, roundPaint);

                Point startPoint3 = new Point(getWidth() / 2 - 5, getHeight() - 5);
                Point endPoint3 = new Point(5, getHeight() / 2 + 5);
                canvas.drawLine(startPoint3, endPoint3, roundPaint);

                pixelMapHolder = null;
            }
        });
    }

    //使用Canvase 切边角
    public void onRoundRectClip(int roundPx) {
        //添加绘制任务
        this.addDrawTask((view, canvas) -> {
            if (pixelMapHolder == null) {
                return;
            }
            synchronized (pixelMapHolder) {
                //给目标区域赋值，宽度和高度取自xml配置文件中的属性
                rectDst = new RectFloat(0, 0, getWidth(), getHeight());
                canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, 0, 0);
                //绘制圆角图片
                canvas.clipRect(rectDst, Canvas.ClipOp.INTERSECT);
                Paint paint = new Paint();
                paint.setAntiAlias(true);                           //设置画笔为无锯齿
                paint.setColor(Color.WHITE);                        //设置画笔颜色

                canvas.drawPath(pathLeftTop(roundPx), paint);
                canvas.drawPath(pathRightTop(roundPx), paint);
                canvas.drawPath(pathLeftBottom(roundPx), paint);
                canvas.drawPath(pathRightBottom(roundPx), paint);
                pixelMapHolder = null;
            }
        });
    }

    /**
     * 设置每个角的路径坐标点
     *
     * @param roundPx
     * @return
     */
    private Path pathLeftTop(int roundPx) {
        Path path = new Path();
        path.moveTo(0, 0);
        path.lineTo(roundPx, 0);
        path.lineTo(0, roundPx);
        path.close();
        return path;
    }

    private Path pathRightTop(int roundPx) {
        Path path = new Path();
        path.moveTo(getWidth(), 0);
        path.lineTo(getWidth() - roundPx, 0);
        path.lineTo(getWidth(), roundPx);
        path.close();
        return path;
    }

    private Path pathRightBottom(int roundPx) {
        Path path = new Path();
        path.moveTo(getWidth(), getHeight());
        path.lineTo(getWidth(), getHeight() - roundPx);
        path.lineTo(getWidth() - roundPx, getHeight());
        path.close();
        return path;
    }

    private Path pathLeftBottom(int roundPx) {
        Path path = new Path();
        path.moveTo(0, getHeight());
        path.lineTo(0, getHeight() - roundPx);
        path.lineTo(roundPx, getHeight());
        path.close();
        return path;
    }


    //使用canvas画带边框园角
    public void onRoundRectAndStrokeDraw(int radius) {
        //添加绘制任务
        this.addDrawTask((view, canvas) -> {
            if (pixelMapHolder == null) {
                return;
            }
            synchronized (pixelMapHolder) {
                //给目标区域赋值，宽度和高度取自xml配置文件中的属性
                rectDst = new RectFloat(0, 0, getWidth(), getHeight());
                //绘制圆角图片
                canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, radius, radius);
                Paint roundPaint = new Paint();
                roundPaint.setAntiAlias(true);
                roundPaint.setStyle(Paint.Style.STROKE_STYLE);
                roundPaint.setStrokeWidth(10);
                roundPaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
                roundPaint.setColor(Color.BLUE);
                RectFloat rectFloat1 = new RectFloat(5, 5, getWidth() - 5, getHeight() - 5);
                canvas.drawRoundRect(rectFloat1, radius - 10, radius - 10, roundPaint);
                pixelMapHolder = null;
            }
        });
    }

    //使用canvas画圆角图形
    public void onRoundRectDraw(int radius) {
        //添加绘制任务
        this.addDrawTask((view, canvas) -> {
            if (pixelMapHolder == null) {
                return;
            }
            synchronized (pixelMapHolder) {
                //给目标区域赋值，宽度和高度取自xml配置文件中的属性
                rectDst = new RectFloat(0, 0, getWidth(), getHeight());
                //绘制圆角图片
                canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, radius, radius);

                pixelMapHolder = null;
            }
        });
    }

    //使用canvas绘制圆形
    private void onCircleDraw() {
        //添加绘制任务，自定义组件的核心api调用，该接口的参数为Component下的DrawTask接口
        this.addDrawTask((view, canvas) -> {
            if (pixelMapHolder == null) {
                return;
            }
            synchronized (pixelMapHolder) {
                //给目标区域赋值，宽度和高度取自xml配置文件中的属性
                rectDst = new RectFloat(0, 0, getWidth(), getHeight());
                //使用canvas绘制输出圆角矩形的位图，该方法第4个参数和第5个参数为radios参数，
                // 绘制图片，必须把图片的宽度和高度先设置成一样，然后把它们设置为图片宽度或者高度一半时则绘制的为圆形
                canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, getWidth() / 2, getHeight() / 2);
                pixelMapHolder = null;
            }
        });
    }


    /**
     * 获取原有Image中的位图资源后重新检验绘制该组件
     *
     * @param pixelMap
     */
    private void putPixelMap(PixelMap pixelMap) {
        if (pixelMap != null) {
            rectSrc = new RectFloat(0, 0, pixelMap.getImageInfo().size.width, pixelMap.getImageInfo().size.height);
            pixelMapHolder = new PixelMapHolder(pixelMap);
            invalidate();//重新检验该组件
        } else {
            pixelMapHolder = null;
            setPixelMap(null);
        }
    }

    /**
     * 通过资源ID获取位图对象
     **/
    private PixelMap getPixelMap(int resId) {
        InputStream drawableInputStream = null;
        try {
            drawableInputStream = getResourceManager().getResource(resId);
            ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
            sourceOptions.formatHint = "image/png";
            ImageSource imageSource = ImageSource.create(drawableInputStream, null);
            ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
            decodingOptions.desiredSize = new Size(0, 0);
            decodingOptions.desiredRegion = new Rect(0, 0, 0, 0);
            decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
            PixelMap pixelMap = imageSource.createPixelmap(decodingOptions);
            return pixelMap;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (drawableInputStream != null) {
                    drawableInputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }


}